<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::net_flow::Send_bandwidth_estimator Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1net__flow.html">net_flow</a></li><li class="navelem"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html">Send_bandwidth_estimator</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-types">Public Types</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pri-methods">Private Member Functions</a> &#124;
<a href="#pri-static-methods">Static Private Member Functions</a> &#124;
<a href="#pri-attribs">Private Attributes</a> &#124;
<a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">flow::net_flow::Send_bandwidth_estimator Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.  
 <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#details">More...</a></p>

<p><code>#include &lt;<a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>&gt;</code></p>
<div class="dynheader">
Inheritance diagram for flow::net_flow::Send_bandwidth_estimator:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Send__bandwidth__estimator__inherit__graph.svg" width="310" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for flow::net_flow::Send_bandwidth_estimator:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Send__bandwidth__estimator__coll__graph.svg" width="1476" height="558"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-types" name="pub-types"></a>
Public Types</h2></td></tr>
<tr class="memitem:a40993b2699c5e8ab69dfd56e57ecdd28"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a> = uint64_t</td></tr>
<tr class="memdesc:a40993b2699c5e8ab69dfd56e57ecdd28"><td class="mdescLeft">&#160;</td><td class="mdescRight">Type that represents the number of bytes, either as an absolute amount or over some time period.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">More...</a><br /></td></tr>
<tr class="separator:a40993b2699c5e8ab69dfd56e57ecdd28"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1e5e59588c6683d56866e49e5fd2980e"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e">Time_unit</a> = boost::chrono::milliseconds</td></tr>
<tr class="memdesc:a1e5e59588c6683d56866e49e5fd2980e"><td class="mdescLeft">&#160;</td><td class="mdescRight">The primary time unit over which this class reports bandwidth.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e">More...</a><br /></td></tr>
<tr class="separator:a1e5e59588c6683d56866e49e5fd2980e"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:ad2432d0e20ebfd1b95009e10f10f08be"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ad2432d0e20ebfd1b95009e10f10f08be">Send_bandwidth_estimator</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, <a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html#aef7998db71c60eeb5d1e3d1a97c14886">Peer_socket::Const_ptr</a> sock)</td></tr>
<tr class="memdesc:ad2432d0e20ebfd1b95009e10f10f08be"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs object by setting up logging and saving a pointer to the containing <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ad2432d0e20ebfd1b95009e10f10f08be">More...</a><br /></td></tr>
<tr class="separator:ad2432d0e20ebfd1b95009e10f10f08be"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a135f0a46b34063e10abfb16de057cbb3"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3">bandwidth_bytes_per_time</a> () const</td></tr>
<tr class="memdesc:a135f0a46b34063e10abfb16de057cbb3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the current estimate of the available outgoing bandwidth per unit time for the containing socket's connection, in units of bytes per <code>Time_unit(1)</code>.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3">More...</a><br /></td></tr>
<tr class="separator:a135f0a46b34063e10abfb16de057cbb3"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afe271b3d4c8cb73d06048a41871c795e"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e">on_acks</a> (size_t bytes)</td></tr>
<tr class="memdesc:afe271b3d4c8cb73d06048a41871c795e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-flight just received acknowledgments, thus changing their state from In-flight to Acknowledged.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e">More...</a><br /></td></tr>
<tr class="separator:afe271b3d4c8cb73d06048a41871c795e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_methods_classflow_1_1log_1_1Log__context"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classflow_1_1log_1_1Log__context')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classflow_1_1log_1_1Log__context.html">flow::log::Log_context</a></td></tr>
<tr class="memitem:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger=0)</td></tr>
<tr class="memdesc:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a null <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a>.  <a href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">More...</a><br /></td></tr>
<tr class="separator:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplParams" colspan="2">template&lt;typename Component_payload &gt; </td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplItemLeft" align="right" valign="top">&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger, Component_payload component_payload)</td></tr>
<tr class="memdesc:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a new <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> storing the specified generically typed payload (an <code>enum</code> value).  <a href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">More...</a><br /></td></tr>
<tr class="separator:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">Log_context</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor that stores equal <code>Logger*</code> and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> values as the source.  <a href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">More...</a><br /></td></tr>
<tr class="separator:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor that makes this equal to <code>src</code>, while the latter becomes as-if default-constructed.  <a href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">More...</a><br /></td></tr>
<tr class="separator:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">operator=</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Assignment operator that behaves similarly to the copy constructor.  <a href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">More...</a><br /></td></tr>
<tr class="separator:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">operator=</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator that behaves similarly to the move constructor.  <a href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">More...</a><br /></td></tr>
<tr class="separator:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">swap</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;other)</td></tr>
<tr class="memdesc:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Swaps <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointers and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> objects held by <code>*this</code> and <code>other</code>.  <a href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">More...</a><br /></td></tr>
<tr class="separator:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">get_logger</a> () const</td></tr>
<tr class="memdesc:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the stored <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointer, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">More...</a><br /></td></tr>
<tr class="separator:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="classflow_1_1log_1_1Component.html">Component</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">get_log_component</a> () const</td></tr>
<tr class="memdesc:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns reference to the stored <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> object, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">More...</a><br /></td></tr>
<tr class="separator:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-methods" name="pri-methods"></a>
Private Member Functions</h2></td></tr>
<tr class="memitem:a8676142f693c447be89b667403fecea1"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html#aef7998db71c60eeb5d1e3d1a97c14886">Peer_socket::Const_ptr</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a8676142f693c447be89b667403fecea1">socket</a> () const</td></tr>
<tr class="memdesc:a8676142f693c447be89b667403fecea1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Utility that returns a handle to the containing <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a8676142f693c447be89b667403fecea1">More...</a><br /></td></tr>
<tr class="separator:a8676142f693c447be89b667403fecea1"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-static-methods" name="pri-static-methods"></a>
Static Private Member Functions</h2></td></tr>
<tr class="memitem:a2d19118df3aa42de866343893dc75a0a"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a2d19118df3aa42de866343893dc75a0a">apply_filter</a> (<a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a> prev_val_per_time, <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a> new_sample_val_per_time)</td></tr>
<tr class="memdesc:a2d19118df3aa42de866343893dc75a0a"><td class="mdescLeft">&#160;</td><td class="mdescRight">Applies the low-pass filter that takes the given previous result of the filter and blends in the given new sample.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a2d19118df3aa42de866343893dc75a0a">More...</a><br /></td></tr>
<tr class="separator:a2d19118df3aa42de866343893dc75a0a"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pri-attribs" name="pri-attribs"></a>
Private Attributes</h2></td></tr>
<tr class="memitem:a380927913e47235684ce014b14371920"><td class="memItemLeft" align="right" valign="top">boost::weak_ptr&lt; Peer_socket::Const_ptr::element_type &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a380927913e47235684ce014b14371920">m_sock</a></td></tr>
<tr class="memdesc:a380927913e47235684ce014b14371920"><td class="mdescLeft">&#160;</td><td class="mdescRight">The containing socket (read-only access).  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a380927913e47235684ce014b14371920">More...</a><br /></td></tr>
<tr class="separator:a380927913e47235684ce014b14371920"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aee344345b4b4c54a0854bfd23817ef46"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#aee344345b4b4c54a0854bfd23817ef46">m_bytes_per_time_smoothed</a></td></tr>
<tr class="memdesc:aee344345b4b4c54a0854bfd23817ef46"><td class="mdescLeft">&#160;</td><td class="mdescRight">The current smoothed bandwidth estimate, to be returned by <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a>, in the units described by that method's doc header.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#aee344345b4b4c54a0854bfd23817ef46">More...</a><br /></td></tr>
<tr class="separator:aee344345b4b4c54a0854bfd23817ef46"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae6e40f0e24775a09a60dcb7d18242a02"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ae6e40f0e24775a09a60dcb7d18242a02">m_bytes_per_time_less_smoothed</a></td></tr>
<tr class="memdesc:ae6e40f0e24775a09a60dcb7d18242a02"><td class="mdescLeft">&#160;</td><td class="mdescRight">In the same units as <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#aee344345b4b4c54a0854bfd23817ef46" title="The current smoothed bandwidth estimate, to be returned by bandwidth_bytes_per_time(),...">m_bytes_per_time_smoothed</a>, the less smoothed bandwidth estimate, which is simply the progressive application of <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a2d19118df3aa42de866343893dc75a0a" title="Applies the low-pass filter that takes the given previous result of the filter and blends in the give...">apply_filter()</a> on each available bandwidth sample.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ae6e40f0e24775a09a60dcb7d18242a02">More...</a><br /></td></tr>
<tr class="separator:ae6e40f0e24775a09a60dcb7d18242a02"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0bf439f5cfe98fb1d4d6d55ae605d278"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a0bf439f5cfe98fb1d4d6d55ae605d278">m_bytes_this_sample</a></td></tr>
<tr class="memdesc:a0bf439f5cfe98fb1d4d6d55ae605d278"><td class="mdescLeft">&#160;</td><td class="mdescRight">The number of bytes acknowledged by receiver since <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ac627f8c9ae6c51c2ea14dd46af4f4150" title="The time at which the currently ongoing bandwidth sample began to accumulate.">m_this_sample_start_time</a> (the time when the current sample began to be compiled).  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a0bf439f5cfe98fb1d4d6d55ae605d278">More...</a><br /></td></tr>
<tr class="separator:a0bf439f5cfe98fb1d4d6d55ae605d278"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac627f8c9ae6c51c2ea14dd46af4f4150"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ac627f8c9ae6c51c2ea14dd46af4f4150">m_this_sample_start_time</a></td></tr>
<tr class="memdesc:ac627f8c9ae6c51c2ea14dd46af4f4150"><td class="mdescLeft">&#160;</td><td class="mdescRight">The time at which the currently ongoing bandwidth sample began to accumulate.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ac627f8c9ae6c51c2ea14dd46af4f4150">More...</a><br /></td></tr>
<tr class="separator:ac627f8c9ae6c51c2ea14dd46af4f4150"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:adc8e7ca2c14f74a85beb863c145b97ba"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classbool.html">bool</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#adc8e7ca2c14f74a85beb863c145b97ba">m_no_acks_yet</a></td></tr>
<tr class="memdesc:adc8e7ca2c14f74a85beb863c145b97ba"><td class="mdescLeft">&#160;</td><td class="mdescRight"><code>true</code> until <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> called for the first time; <code>false</code> forever thereafter. Used to begin the sample sequence.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#adc8e7ca2c14f74a85beb863c145b97ba">More...</a><br /></td></tr>
<tr class="separator:adc8e7ca2c14f74a85beb863c145b97ba"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac89711897d0c265eb3b18a748c03d3aa"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classbool.html">bool</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ac89711897d0c265eb3b18a748c03d3aa">m_no_samples_yet</a></td></tr>
<tr class="memdesc:ac89711897d0c265eb3b18a748c03d3aa"><td class="mdescLeft">&#160;</td><td class="mdescRight"><code>true</code> until a sample has been completed and fed into the filter; <code>false</code> forever thereafter.  <a href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ac89711897d0c265eb3b18a748c03d3aa">More...</a><br /></td></tr>
<tr class="separator:ac89711897d0c265eb3b18a748c03d3aa"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow. </p>
<p >That is, it tries to get at the # of bytes per unit time the outgoing empty pipe can support, minus the # of bytes per unit time being transferred by all other flows in that pipe (NetFlow or otherwise). This is useful primarily for certain congestion control strategies (like <a class="el" href="classflow_1_1net__flow_1_1Congestion__control__classic__with__bandwidth__est.html" title="Classic congestion control but with backoff to bandwidth estimate-based pipe size.">Congestion_control_classic_with_bandwidth_est</a>) but may also be good information to make available to the application layer (e.g., if the user wants to inform a media player what is a suitable bit rate to avoid rebuffering). The latter is the reason why <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> is not part of a congestion control strategy but rather a separate class.</p>
<p >How can we make this estimate? As a black box, we care about just one event, <code>on_acks(N)</code>, where <code>N</code> is the number of bytes that have been cleanly acknowledged by the receiver. The <code><a class="el" href="namespaceflow_1_1net__flow.html" title="Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...">net_flow</a></code> engine should inform this module about each such event. The running bandwidth estimate is then available via <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a>.</p>
<h3>Object life cycle</h3>
<p >There is a strict 1-to-1 relationship between one <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> instance and one <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>. A <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> is created shortly after <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> is and is saved inside the latter. Conversely a pointer to the <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> is stored inside the <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> (for read-only access to stats such as SRTT). The containing <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> must exist at all times while <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> exists. Informally it's recommended that <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> destructor or other method deletes its <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> instance when it is no longer needed.</p>
<p >Relationship with outside world:</p>
<ol type="1">
<li><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> is a black box to <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> and <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> code (no access to internals; access only to constructors/destructor and API).</li>
<li><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> has <code>const</code> (!) <code>friend</code> access to <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> internals.</li>
<li>The programmer of <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> must assume a certain event model to be followed by <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a>. This model is to be explicitly explained in the doc headers for any <code>on_...()</code> methods. <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> must call the <code>on_...()</code> methods as soon as it detects the appropriate events, and it should aim to detect them as soon as possible after they occur.</li>
<li>The programmer of <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> subclass may assume the existence and meaning of certain state of <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>, which she can use to make internal computations. Any such state (i.e., in addition to the on-event calls, and their arguments, in (3)) must be explicitly documented in the class or method doc headers.</li>
<li>Informally, it is assumed that the <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> is sending data at a rate close to the available capacity of the pipe at all times (and thus the resulting <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> events reflect this available maximum possible speed). (Of course this can only be a best effort and cannot be guaranteed; indeed <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> itself can help the congestion control mechanism in use to maintain a sending rate close to the maximum possible, which in turn will feed good acknowledgment samples to <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a>. It sounds like a circular technique, but it can work well.)</li>
</ol>
<p >Note that the assumption in (5) can also not hold if the sending rate (and thus the rate of returning acknowledgments) is application-limited; that is the user is not sending data as fast <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a> allows, or in particular simply not sending data. In that case the bandwidth readings may be inaccurately low (very much so possibly). Therefore only rely on the results of this class when not application-limited in this way.</p>
<h3>Units</h3>
<p ><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a> returns the current bandwidth estimate per unit time U, as an <em>integer</em> number of bytes (rounded down). What is U? U is given as <code>Time_unit(1)</code>, where <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e" title="The primary time unit over which this class reports bandwidth.">Time_unit</a> is a public alias of a boost.chrono duration type. Be careful in any arithmetic done with the value returned; both overflow and underflow can occur, if one does not take care to sanity-check the arithmetic. The justification for the value of the <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e" title="The primary time unit over which this class reports bandwidth.">Time_unit</a> alias is given in the <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e" title="The primary time unit over which this class reports bandwidth.">Time_unit</a> doc header.</p>
<h3>Thread safety</h3>
<p >Unless stated otherwise, a <a class="el" href="classflow_1_1net__flow_1_1Congestion__control__strategy.html" title="The abstract interface for a per-socket module that determines the socket&#39;s congestion control behavi...">Congestion_control_strategy</a> object is to be accessed from the containing <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>'s <a class="el" href="classflow_1_1net__flow_1_1Node.html" title="An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...">Node</a>'s thread W only.</p>
<h2>Implementation notes </h2>
<p >How do we estimate the available bandwidth? Basically, we assume the sender &ndash; whenever giving us <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> events &ndash; is sending data at the maximum possible rate. Therefore, if we divide the </p><h1>of bytes reported in acknowledgments by the time period over which we've accumulated those</h1>
<p >acknowledgments, then we know the available bandwidth over that time period. Such bandwidth samples can be blended with past samples using a low-pass filter to get a smoothed bandwidth estimate. Of course the question arises: what time period to choose, and what filter to use? We use the Westwood+ algorithm that answers these questions. The basic idea is to maintain a byte count that starts at 0 at the beginning of the sample period and keeps accumulating as the acknowledgments come in; once the sample period &gt; SRTT (smoothed round trip time of the socket), the bytes/time bandwidth sample is taken and added into the running filter; and the new sample begins with the byte count at 0. The justification for these choices is given, partially, in the code and, more completely, in the papers referenced below.</p>
<p >Why not make this a strategy pattern (like <a class="el" href="classflow_1_1net__flow_1_1Congestion__control__strategy.html" title="The abstract interface for a per-socket module that determines the socket&#39;s congestion control behavi...">Congestion_control_strategy</a> hierarchy) instead of just a single class, so that multiple ways of bandwidth estimation can exist? Because, as far as I know, Westwood+ is the best available technique, so I don't see the point of doing anything else. If that changes, revisit this.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000075">Todo:</a></b></dt><dd>Look into Google BBR, a recent (as of 2016) state-of-the-art congestion control algorithm that aims to estimate bandwidth among other things. Depending on what what one decides, another bandwidth estimator class could be written.</dd></dl>
<dl class="section see"><dt>See also</dt><dd>Linux kernel's <code>tcp_westwood.c</code> for inspiration behind this implementation; the top comment in that file also cites the main papers that describe the Westwood+ bandwidth estimator. </dd></dl>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00122">122</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>
</div><h2 class="groupheader">Member Typedef Documentation</h2>
<a id="a40993b2699c5e8ab69dfd56e57ecdd28" name="a40993b2699c5e8ab69dfd56e57ecdd28"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a40993b2699c5e8ab69dfd56e57ecdd28">&#9670;&nbsp;</a></span>n_bytes_t</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">flow::net_flow::Send_bandwidth_estimator::n_bytes_t</a> =  uint64_t</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Type that represents the number of bytes, either as an absolute amount or over some time period. </p>
<p >To avoid any surprises we set its width explicitly instead of using <code>size_t</code>. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00134">134</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

</div>
</div>
<a id="a1e5e59588c6683d56866e49e5fd2980e" name="a1e5e59588c6683d56866e49e5fd2980e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1e5e59588c6683d56866e49e5fd2980e">&#9670;&nbsp;</a></span>Time_unit</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e">flow::net_flow::Send_bandwidth_estimator::Time_unit</a> =  boost::chrono::milliseconds</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>The primary time unit over which this class reports bandwidth. </p>
<p >So when <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a> return the number N, that means its bandwidth estimate is N bytes per <code>Time_unit(1)</code> time.</p>
<h3>Implementation notes</h3>
<p >Why choose milliseconds? There are two conflicting constraints on <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e" title="The primary time unit over which this class reports bandwidth.">Time_unit</a>. In the basic bandwidth sample computation, the formula is B = N/D, where N is the number of bytes acknowledged over time period D, and D is a <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a>. Note that B is an integer (<a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28" title="Type that represents the number of bytes, either as an absolute amount or over some time period.">n_bytes_t</a>), as we try to avoid floating-point computations, so the division rounds down. <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">Fine_duration</a>, we can assume, is at least nanoseconds (10^-9 seconds).</p>
<p >If <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e" title="The primary time unit over which this class reports bandwidth.">Time_unit</a> is something large, like seconds, then in the straightforward B = N/D formula nanoseconds must first be converted (with integer math only!) to seconds. This loses a ton of precision in D, which will typically be something like .001-.2 seconds (up to about an RTT). That's clearly unacceptable. If <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e" title="The primary time unit over which this class reports bandwidth.">Time_unit</a> is something tiny, like nanoseconds, then N/D's minimum non-zero value (1) will represent 10^9 bytes per second (all lower bandwidths B rounding down to zero), which is clearly absurd. What about milliseconds? RTTs are classically given in milliseconds anyway, so the precision is acceptable (though <a class="el" href="namespaceflow.html#a8f2e48761f9ca3ffcaa29872078bbf00" title="Clock used for delicate time measurements, such that the now() method gets the current time relative ...">Fine_clock</a> can in fact give much more precise values &ndash; but that precision is not necessary here). Meanwhile, the lowest value B = N/D = 1 represents 1000 bytes per second, which is definitely a very low bandwidth and thus good enough. So, we use milliseconds.</p>
<p >Another important reason milliseconds is a reasonable unit is in the outside CWND = B * RTTmin calculation (see <a class="el" href="classflow_1_1net__flow_1_1Congestion__control__classic__with__bandwidth__est.html" title="Classic congestion control but with backoff to bandwidth estimate-based pipe size.">Congestion_control_classic_with_bandwidth_est</a>), where CWND is the congestion window, B is the bandwidth estimate we generate, and RTTmin is some RTT. Assuming RTTmin is also in units of <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a1e5e59588c6683d56866e49e5fd2980e" title="The primary time unit over which this class reports bandwidth.">Time_unit</a>, and we use a very large unit for B, then the result of that calculation may actually exceed 64 bits, which will cause overflow. On the other hand if we just express B in bytes/ms and RTTmin in ms, then the formula avoids that danger while being quite precise enough. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00167">167</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="ad2432d0e20ebfd1b95009e10f10f08be" name="ad2432d0e20ebfd1b95009e10f10f08be"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad2432d0e20ebfd1b95009e10f10f08be">&#9670;&nbsp;</a></span>Send_bandwidth_estimator()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::net_flow::Send_bandwidth_estimator::Send_bandwidth_estimator </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html#aef7998db71c60eeb5d1e3d1a97c14886">Peer_socket::Const_ptr</a>&#160;</td>
          <td class="paramname"><em>sock</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructs object by setting up logging and saving a pointer to the containing <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>. </p>
<p ><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a> will return 0 until enough <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> events have occurred to make it receive a higher value, but certainly at least until <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> is called once.</p>
<p >Only a weak pointer of <code>sock</code> is stored: the <code>shared_ptr</code> itself is not saved, so the reference count of <code>sock</code> does not increase. This avoids a circular <code>shared_ptr</code> situation that would arise from <code>*this</code> pointing to <code>sock</code>, and <code>sock</code> pointing to <code>*this</code> (the two objects <em>do</em> need access to each other, as explained in class doc header).</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>The Logger implementation to use subsequently. </td></tr>
    <tr><td class="paramname">sock</td><td>The <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> for which this module will estimate available outgoing bandwidth. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="bandwidth_8cpp_source.html#l00026">26</a> of file <a class="el" href="bandwidth_8cpp_source.html">bandwidth.cpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a2d19118df3aa42de866343893dc75a0a" name="a2d19118df3aa42de866343893dc75a0a"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a2d19118df3aa42de866343893dc75a0a">&#9670;&nbsp;</a></span>apply_filter()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">Send_bandwidth_estimator::n_bytes_t</a> flow::net_flow::Send_bandwidth_estimator::apply_filter </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a>&#160;</td>
          <td class="paramname"><em>prev_val_per_time</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a>&#160;</td>
          <td class="paramname"><em>new_sample_val_per_time</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Applies the low-pass filter that takes the given previous result of the filter and blends in the given new sample. </p>
<p >The values should be in the same units, which are presumably bytes per <code>Time_unit(1)</code>.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">prev_val_per_time</td><td>Previous result of this filter. </td></tr>
    <tr><td class="paramname">new_sample_val_per_time</td><td>New sample to blend into that filter. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>The blended value. </dd></dl>

<p class="definition">Definition at line <a class="el" href="bandwidth_8cpp_source.html#l00231">231</a> of file <a class="el" href="bandwidth_8cpp_source.html">bandwidth.cpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Send__bandwidth__estimator_a2d19118df3aa42de866343893dc75a0a_icgraph.svg" width="344" height="59"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a135f0a46b34063e10abfb16de057cbb3" name="a135f0a46b34063e10abfb16de057cbb3"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a135f0a46b34063e10abfb16de057cbb3">&#9670;&nbsp;</a></span>bandwidth_bytes_per_time()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">Send_bandwidth_estimator::n_bytes_t</a> flow::net_flow::Send_bandwidth_estimator::bandwidth_bytes_per_time </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns the current estimate of the available outgoing bandwidth per unit time for the containing socket's connection, in units of bytes per <code>Time_unit(1)</code>. </p>
<p >This value may be zero if either there is not enough information to make a reasonable estimate, or if the estimated bandwidth is less than a certain low threshold.</p>
<dl class="section return"><dt>Returns</dt><dd>Ditto. </dd></dl>

<p class="definition">Definition at line <a class="el" href="bandwidth_8cpp_source.html#l00038">38</a> of file <a class="el" href="bandwidth_8cpp_source.html">bandwidth.cpp</a>.</p>

<p class="reference">References <a class="el" href="bandwidth_8hpp_source.html#l00275">m_bytes_per_time_smoothed</a>.</p>

</div>
</div>
<a id="afe271b3d4c8cb73d06048a41871c795e" name="afe271b3d4c8cb73d06048a41871c795e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#afe271b3d4c8cb73d06048a41871c795e">&#9670;&nbsp;</a></span>on_acks()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::net_flow::Send_bandwidth_estimator::on_acks </td>
          <td>(</td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>bytes</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-flight just received acknowledgments, thus changing their state from In-flight to Acknowledged. </p>
<p >For efficiency and simplicity of behavior, <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> should be called as few times as possible while still satisfying the requirement in the previous sentence. That is, suppose acknowledgments for N packets were received simultaneously. Then <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> must be called one time, not several times.</p>
<p ><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> must be called <em>after</em> any RTT measurement based on the acked bytes has affected the recorded SRTT in <code>sock</code> passed in constructor.</p>
<p >Additional <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> state used: <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#ad08b53052e7eedfa7a925258f5ef1cba" title="Estimated current round trip time of packets, computed as a smooth value over the past individual RTT...">Peer_socket::m_snd_smoothed_round_trip_time</a>.</p>
<p >Assumptions about ACK sender (DATA received): Same as <a class="el" href="classflow_1_1net__flow_1_1Congestion__control__strategy.html#a832c2c5f72635ef0d5716a9198fd16d4" title="Informs the congestion control strategy that 1 or more previously sent packets whose status was In-fl...">Congestion_control_strategy::on_acks()</a>. However <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html" title="A per-Peer_socket module that tries to estimate the bandwidth available to the outgoing flow.">Send_bandwidth_estimator</a> does not strictly rely on those exact requirements; however it generally expects quick acknowledgments in order to be effective, and <a class="el" href="classflow_1_1net__flow_1_1Congestion__control__strategy.html#a832c2c5f72635ef0d5716a9198fd16d4" title="Informs the congestion control strategy that 1 or more previously sent packets whose status was In-fl...">Congestion_control_strategy::on_acks()</a>'s specific requirements happen to basically satisfy that informal requirement.</p>
<dl class="section note"><dt>Note</dt><dd><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a> may return a different value after this call. If something, like congestion control, relies on that value and can be reasonably be called right after or right before this <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a>, recommend calling it right after this <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a>. </dd>
<dd>
Acknowledgments of data that are not currently In-flight due to being Dropped (a/k/a late ACKs) or Acknowledged (i.e., duplicate ACKs) must NOT be passed to this method. </dd>
<dd>
<a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> makes no assumptions about how the reported individual packet acks were packaged by the ACK sender into actual ACK packets (how many ACKs there were, etc.). It just assumes every individual acknowledgment is reported to <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> as soon as possible and grouped into as few <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> calls as possible. </dd>
<dd>
For definition of In-flight, Acknowledged, and Dropped bytes, see <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a5ea56c54a98289211fef4a672432a2ad" title="The collection of all In-flight packets, indexed by sequence number and ordered from most to least re...">Peer_socket::m_snd_flying_pkts_by_sent_when</a> and <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html#a2db7d11ece920d4adcacd00eaa2253fd" title="The collection of all In-flight packets (including those queued up to send in pacing module),...">Peer_socket::m_snd_flying_pkts_by_seq_num</a>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">bytes</td><td>The sum of the number of bytes in the user data fields of the packets that have been Acknowledged. Must not be zero. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="bandwidth_8cpp_source.html#l00043">43</a> of file <a class="el" href="bandwidth_8cpp_source.html">bandwidth.cpp</a>.</p>

<p class="reference">References <a class="el" href="bandwidth_8cpp_source.html#l00231">apply_filter()</a>, <a class="el" href="log_8hpp_source.html#l00227">FLOW_LOG_TRACE</a>, <a class="el" href="log_8hpp_source.html#l00152">FLOW_LOG_WARNING</a>, <a class="el" href="bandwidth_8hpp_source.html#l00288">m_bytes_per_time_less_smoothed</a>, <a class="el" href="bandwidth_8hpp_source.html#l00275">m_bytes_per_time_smoothed</a>, <a class="el" href="bandwidth_8hpp_source.html#l00295">m_bytes_this_sample</a>, <a class="el" href="bandwidth_8hpp_source.html#l00301">m_no_acks_yet</a>, <a class="el" href="bandwidth_8hpp_source.html#l00307">m_no_samples_yet</a>, <a class="el" href="bandwidth_8hpp_source.html#l00298">m_this_sample_start_time</a>, and <a class="el" href="bandwidth_8cpp_source.html#l00238">socket()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Send__bandwidth__estimator_afe271b3d4c8cb73d06048a41871c795e_cgraph.svg" width="344" height="131"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a8676142f693c447be89b667403fecea1" name="a8676142f693c447be89b667403fecea1"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a8676142f693c447be89b667403fecea1">&#9670;&nbsp;</a></span>socket()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1util_1_1Shared__ptr__alias__holder.html#aef7998db71c60eeb5d1e3d1a97c14886">Peer_socket::Const_ptr</a> flow::net_flow::Send_bandwidth_estimator::socket </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Utility that returns a handle to the containing <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>. </p>
<p >If somehow the containing <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a> has been deleted, <code>assert()</code> trips.</p>
<dl class="section return"><dt>Returns</dt><dd>Ditto. </dd></dl>

<p class="definition">Definition at line <a class="el" href="bandwidth_8cpp_source.html#l00238">238</a> of file <a class="el" href="bandwidth_8cpp_source.html">bandwidth.cpp</a>.</p>

<p class="reference">References <a class="el" href="bandwidth_8hpp_source.html#l00269">m_sock</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1net__flow_1_1Send__bandwidth__estimator_a8676142f693c447be89b667403fecea1_icgraph.svg" width="344" height="59"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<h2 class="groupheader">Member Data Documentation</h2>
<a id="ae6e40f0e24775a09a60dcb7d18242a02" name="ae6e40f0e24775a09a60dcb7d18242a02"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae6e40f0e24775a09a60dcb7d18242a02">&#9670;&nbsp;</a></span>m_bytes_per_time_less_smoothed</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a> flow::net_flow::Send_bandwidth_estimator::m_bytes_per_time_less_smoothed</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>In the same units as <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#aee344345b4b4c54a0854bfd23817ef46" title="The current smoothed bandwidth estimate, to be returned by bandwidth_bytes_per_time(),...">m_bytes_per_time_smoothed</a>, the less smoothed bandwidth estimate, which is simply the progressive application of <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a2d19118df3aa42de866343893dc75a0a" title="Applies the low-pass filter that takes the given previous result of the filter and blends in the give...">apply_filter()</a> on each available bandwidth sample. </p>
<p >It's not used by <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a> but instead is blended into <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#aee344345b4b4c54a0854bfd23817ef46" title="The current smoothed bandwidth estimate, to be returned by bandwidth_bytes_per_time(),...">m_bytes_per_time_smoothed</a>.</p>
<p >I do not really understand why <code>tcp_westwood.c</code> (Linux kernel) does it that way; I get that it adds an extra level of smoothing, but I did not catch any obvious references to this in the papers. Perhaps this is some elementary math that is just assumed to be understood. Anyway, I took it from <code>tcp_westwood.c</code>. Their comment on the equivalent data member <code>bw_ns_est</code> says: "first bandwidth estimation..not too smoothed 8)" which is not too helpful to me. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00288">288</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>

</div>
</div>
<a id="aee344345b4b4c54a0854bfd23817ef46" name="aee344345b4b4c54a0854bfd23817ef46"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aee344345b4b4c54a0854bfd23817ef46">&#9670;&nbsp;</a></span>m_bytes_per_time_smoothed</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a> flow::net_flow::Send_bandwidth_estimator::m_bytes_per_time_smoothed</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The current smoothed bandwidth estimate, to be returned by <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a135f0a46b34063e10abfb16de057cbb3" title="Returns the current estimate of the available outgoing bandwidth per unit time for the containing soc...">bandwidth_bytes_per_time()</a>, in the units described by that method's doc header. </p>
<p >Zero until the first sample is completed. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00275">275</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00038">bandwidth_bytes_per_time()</a>, and <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>

</div>
</div>
<a id="a0bf439f5cfe98fb1d4d6d55ae605d278" name="a0bf439f5cfe98fb1d4d6d55ae605d278"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0bf439f5cfe98fb1d4d6d55ae605d278">&#9670;&nbsp;</a></span>m_bytes_this_sample</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#a40993b2699c5e8ab69dfd56e57ecdd28">n_bytes_t</a> flow::net_flow::Send_bandwidth_estimator::m_bytes_this_sample</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The number of bytes acknowledged by receiver since <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#ac627f8c9ae6c51c2ea14dd46af4f4150" title="The time at which the currently ongoing bandwidth sample began to accumulate.">m_this_sample_start_time</a> (the time when the current sample began to be compiled). </p>
<p >When a sample is deemed sufficient, <code>m_bytes_this_sample / (now() - m_this_sample_start_time)</code> is the individual bandwidth sample fed into the filter. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00295">295</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>

</div>
</div>
<a id="adc8e7ca2c14f74a85beb863c145b97ba" name="adc8e7ca2c14f74a85beb863c145b97ba"></a>
<h2 class="memtitle"><span class="permalink"><a href="#adc8e7ca2c14f74a85beb863c145b97ba">&#9670;&nbsp;</a></span>m_no_acks_yet</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classbool.html">bool</a> flow::net_flow::Send_bandwidth_estimator::m_no_acks_yet</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p><code>true</code> until <a class="el" href="classflow_1_1net__flow_1_1Send__bandwidth__estimator.html#afe271b3d4c8cb73d06048a41871c795e" title="Informs the bandwidth estimator strategy that 1 or more previously sent packets whose status was In-f...">on_acks()</a> called for the first time; <code>false</code> forever thereafter. Used to begin the sample sequence. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00301">301</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>

</div>
</div>
<a id="ac89711897d0c265eb3b18a748c03d3aa" name="ac89711897d0c265eb3b18a748c03d3aa"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac89711897d0c265eb3b18a748c03d3aa">&#9670;&nbsp;</a></span>m_no_samples_yet</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classbool.html">bool</a> flow::net_flow::Send_bandwidth_estimator::m_no_samples_yet</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p><code>true</code> until a sample has been completed and fed into the filter; <code>false</code> forever thereafter. </p>
<p >Used to begin the sample sequence. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00307">307</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>

</div>
</div>
<a id="a380927913e47235684ce014b14371920" name="a380927913e47235684ce014b14371920"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a380927913e47235684ce014b14371920">&#9670;&nbsp;</a></span>m_sock</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">boost::weak_ptr&lt;Peer_socket::Const_ptr::element_type&gt; flow::net_flow::Send_bandwidth_estimator::m_sock</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The containing socket (read-only access). </p>
<p >Implementation may rely on various state stored inside the pointed-to <a class="el" href="classflow_1_1net__flow_1_1Peer__socket.html" title="A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...">Peer_socket</a>.</p>
<p >Why <code>weak_ptr</code>? See similar comment on <a class="el" href="classflow_1_1net__flow_1_1Congestion__control__strategy.html#a1da6833e0c23d111432cbdd3f5451180" title="The containing socket (read-only access).">Congestion_control_strategy::m_sock</a>. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00269">269</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00238">socket()</a>.</p>

</div>
</div>
<a id="ac627f8c9ae6c51c2ea14dd46af4f4150" name="ac627f8c9ae6c51c2ea14dd46af4f4150"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac627f8c9ae6c51c2ea14dd46af4f4150">&#9670;&nbsp;</a></span>m_this_sample_start_time</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a> flow::net_flow::Send_bandwidth_estimator::m_this_sample_start_time</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">private</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>The time at which the currently ongoing bandwidth sample began to accumulate. </p>

<p class="definition">Definition at line <a class="el" href="bandwidth_8hpp_source.html#l00298">298</a> of file <a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="bandwidth_8cpp_source.html#l00043">on_acks()</a>.</p>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>net_flow/detail/stats/<a class="el" href="bandwidth_8hpp_source.html">bandwidth.hpp</a></li>
<li>net_flow/detail/stats/<a class="el" href="bandwidth_8cpp_source.html">bandwidth.cpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:36 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
